using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Threading;
using System.Reflection;

namespace PengYouClient
{
    public partial class OpenVersion : Form
    {
        DavContext context;
        DavRessource ressource;

        string docname;
        string docpath;

        Connect connect;
        Word._Application app;

        Thread reportTh;

        public ArrayList versions;
        public bool getVersion;
        public bool errGetVersion;

        Open_Download Dialog;

        public OpenVersion(Word._Application app, Connect connect)
        {
            this.app = app;
            this.connect = connect;
            InitializeComponent();
        }

        public class FileComparer : IComparer
        {
            public FileComparer() : base() { }

            int IComparer.Compare(object a, object b)
            {
                Hashtable x = (Hashtable)a;
                Hashtable y = (Hashtable)b;
                int verY, verX;

                if (y["version-name"].ToString().Contains("."))
                {
                    string[] versionYtab = y["version-name"].ToString().Split('.');
                    string[] versionXtab = x["version-name"].ToString().Split('.');
                    verY = Convert.ToInt32(versionYtab[1].ToString());
                    verX = Convert.ToInt32(versionXtab[1].ToString());
                }
                else
                {
                    verY = Convert.ToInt32(y["version-name"].ToString());
                    verX = Convert.ToInt32(x["version-name"].ToString());
                }

                //return (((string)y["version-name"]).CompareTo((string)x["version-name"]));
                return (verY - verX);
            }
        }

        private void LaunchErrorWindow(string errormsg)
        {
            string caption = "Connection error";
            MessageBoxButtons buttons = MessageBoxButtons.OK;
            DialogResult result;

            result = MessageBox.Show(this, errormsg, caption, buttons);
            if (result == DialogResult.OK)
            {
                this.Close();
            }
        }

        private void PutVersionInList()
        {
            this.versions.Sort(new FileComparer());
            IEnumerator dicenum = this.versions.GetEnumerator();
            while (dicenum.MoveNext())
            {
                string lastmodified = ((Hashtable)dicenum.Current)["version-lastmodified"].ToString();
                string versionname = ((Hashtable)dicenum.Current)["version-name"].ToString();
                string owner = ((Hashtable)dicenum.Current)["version-owner"].ToString();
                string comment = ((Hashtable)dicenum.Current)["version-comment"].ToString();

                System.Windows.Forms.ListViewItem Ligne = new System.Windows.Forms.ListViewItem(new string[] {
                    versionname,
                    owner,
                    lastmodified,
                    comment});
                this.ListViewVersion.Items.Add(Ligne);
            }
        }

        public class reportThread
        {
            OpenVersion openVersion;
            ArrayList versions;

            public reportThread(OpenVersion openVersion)
            {
                this.openVersion = openVersion;
                this.openVersion.getVersion = false;
                this.openVersion.errGetVersion = false;
            }

            public void reportThreadRun()
            {
                this.versions = new ArrayList();
                bool success = 
                    openVersion.ressource.Report(out this.versions);
                if (success == false)
                    openVersion.errGetVersion = true;
                openVersion.versions = this.versions;
                if (this.openVersion.errGetVersion == true)
                    this.openVersion.getVersion = false;
                else
                    this.openVersion.getVersion = true;
            }
        }

        private void LaunchreportThread()
        {
            reportThread h_report = new reportThread(this);
            this.reportTh = new Thread(new ThreadStart(h_report.reportThreadRun));
            this.reportTh.Start();            
        }

        private void SetText()
        {
            Version.Text = LanguageManager.GetString("WindowOpenVersionVersion");
            Author.Text = LanguageManager.GetString("WindowOpenVersionAuthor");
            Date.Text = LanguageManager.GetString("WindowOpenVersionDate");
            Comment.Text = LanguageManager.GetString("WindowOpenVersionComment");
            LinkShowDifferences.Text = LanguageManager.GetString("WindowOpenVersionShowDiff");
            ButtonOpen.Text = LanguageManager.GetString("WindowOpenVersionOpen");
            ButtonClose.Text = LanguageManager.GetString("WindowOpenVersionClose");
        }

        private void OpenVersion_Load(object sender, EventArgs e)
        {
            SetText();
            if (app.Documents.Count == 0)
                LaunchErrorWindow(LanguageManager.GetString("WindowOpenVersionNoDocument"));
            if (!pengyouUtils.GetWordDocumentProp(app, "PengYouDocName", out docname))
                LaunchErrorWindow(LanguageManager.GetString("WindowOpenVersionDocProperties"));
            if (!pengyouUtils.GetWordDocumentProp(app, "PengYouBaseDir", out docpath))
                LaunchErrorWindow(LanguageManager.GetString("WindowOpenVersionDocProperties"));
            docname = HttpUtility.UrlPathEncode(docname);
            if (!docpath.EndsWith("/"))
                docpath += "/";
            string ressourcePath = SettingsManager.Server_host + ":" + 
                SettingsManager.Server_port + SettingsManager.Ressource_basedir + docpath + docname;
            this.Text = LanguageManager.GetString("WindowOpenVersionVersionFor") + HttpUtility.UrlDecode(docname);

            this.context = new DavContext(SettingsManager.Server_host, Convert.ToInt32(SettingsManager.Server_port),
                SettingsManager.Server_user, SettingsManager.Server_pass);
            this.ressource = new DavRessource(ressourcePath, this.context);
        }

        private void OpenVersion_Shown(object sender, EventArgs e)
        {
            LaunchreportThread();
            if (getVersion == false)
            {
                ReportProgressBar bar = new ReportProgressBar(this);
                bar.ShowDialog();
            }
            reportTh.Join();
            if (getVersion == false && errGetVersion == true)
                LaunchErrorWindow(LanguageManager.GetString("WindowOpenVersionUnableGetVersion"));
            else
                PutVersionInList();
        }

        private string extractValue(string versionName, string value)
        {
            IEnumerator dicenum = this.versions.GetEnumerator();
            while (dicenum.MoveNext())
            {
                if (versionName.CompareTo(((Hashtable)dicenum.Current)["version-name"].ToString()) == 0)
                    return (((Hashtable)dicenum.Current)[value].ToString());
            }
            return "";
        }


        private void ListViewVersion_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                string item = ((ListView)sender).FocusedItem.Text;
                string comment = extractValue(item, "version-comment");
                this.CommentTextBox.Text = comment;
            }
            catch (Exception)
            {
            }
        }

        private void ButtonClose_Click(object sender, EventArgs e)
        {
            reportTh.Abort();
            this.Close();
        }

        private void LinkShowDifferences_Click(object sender, EventArgs e)
        {
            bool selectItem;
            string item = "";
            try
            {
                item = ListViewVersion.FocusedItem.Text;
                selectItem = true;
            }
            catch (Exception)
            {
                selectItem = false;
            }

            if (selectItem == true)
            {                
                if (DownloadFile(item))
                    connect.compareversion = true;
                this.Close();
            }
        }

        private bool DownloadFile(string item)
        {
            string ressource = extractValue(item, "version-href");
            string version = extractValue(item, "version-name");
            object omissing = Missing.Value;
            DavRessource Dav = new DavRessource(ressource, this.context);

            Dialog = new Open_Download(Dav);
            Dialog.ShowDialog();

            if (Dialog.GetRemoteFile == false)
            {                
                LaunchErrorWindow(Dav.ResultReason);
                return false;
            }
            else
            {
                connect.Docbasedir = this.docpath;
                connect.Filename = HttpUtility.UrlDecode(Dialog.RemoteFile.Name);
                connect.ParentName = HttpUtility.UrlDecode(docname);
                connect.RealFilename = HttpUtility.UrlDecode(version + "-" + docname);
            }
            return true;
        }

        private void ButtonOpen_Click(object sender, EventArgs e)
        {
            bool selectItem;
            string item = "";
            try
            {
                item = ListViewVersion.FocusedItem.Text;
                selectItem = true;
            }
            catch (Exception)
            {
                selectItem = false;
            }

            if (selectItem == true)
            {
                DownloadFile(item);
                this.Close();
            }
        }
    }
}